package com.hbnu.reflect;

import java.lang.reflect.*;
import java.sql.ParameterMetaData;

public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        //获取字节码对象，

        //通过class属性
        Class personClass = Person.class;//任何类都会有class属性

        //通过对象的getClass方法获取该类的字节码对象
        Person person = new Person("K", 66);
        Class personClass2 = person.getClass();


        //通过Class类的forName方法获取指定类的字节码对象
        Class aClass = Class.forName("com.hbnu.reflect.Person");


        //获取所有的公共构造方法
        Constructor[] constructors = aClass.getConstructors();
        System.out.println("公共构造方法的个数："+constructors.length);
        for (Constructor constructor : constructors){
            String name = constructor.getName();
            Parameter[] parameters = constructor.getParameters();
            for (Parameter parameter : parameters) {

                System.out.println(parameter.getParameterizedType());
                System.out.println("构造方法的参数名"+parameters.length);
            }
        }


        //获取所有的构造方法
        System.out.println("所有的构造方法");
        System.out.println();
        Constructor[] constructors1 = aClass.getDeclaredConstructors();
        System.out.println("所有的构造方法个数"+constructors1.length+"\t");
        for (Constructor constructor : constructors1) {
            String name = constructor.getName();
            System.out.println("构造方法的名字"+name+"\t");
            Parameter[] parameters = constructor.getParameters();
            System.out.println("构造方法参数个数"+parameters.length+"\t");
            for (Parameter parameter : parameters) {
                System.out.println(parameter.getParameterizedType()+"\t");
                System.out.println("构造方法的参数名"+parameter.getName()+"\t");
            }
            System.out.println();
        }

        //通过构造方法创建对象，
        System.out.println("1.3获取指定的公共构造方法");
        Constructor constructor = aClass.getConstructor(String.class,int.class);            //通过反射的方式创建对象

        Person person1 = (Person) constructor.newInstance("1", 20);
        System.out.println(person1.getUsername());


        //获取所有的公共属性
        Field[] fields = aClass.getFields();
        System.out.println("所有公共属性的数量"+fields.length);
        for (Field field : fields) {
            String name = field.getName();
            Class<?> type = field.getType();
            System.out.println("属性名："+name+"\t属性类型"+type);
        }

        //获取所有的属性
        Field[] fields1 = aClass.getDeclaredFields();
        System.out.println("获取所有的属性的数量"+fields1.length);
        for (Field field : fields1) {
            String name = field.getName();
            Class<?> type = field.getType();
            System.out.println("属性名："+name+"\t属性类型"+type);
        }


        //获取某个具体的属性
        System.out.println("获取某个具体的公共属性");
        Person obj1 = (Person) aClass.newInstance();
        Field field = aClass.getField("address");
        field.set(obj1,"湖师");
        System.out.println(obj1.getAddress());

        System.out.println("获取某个具体的私有属性");
        Field field1 = aClass.getDeclaredField("username");
        field1.setAccessible(true);                                 //设置私有变量可以访问
        field1.set(obj1,"john");
        System.out.println(obj1.getUsername());

        //获取所有的公共方法///////////////////////////////////////////////////
        System.out.println("获取所有的公共方法");
        Method[] methods1 = aClass.getMethods();
        System.out.println("所有公共构造方法个数："+methods1.length);
        for (Method method : methods1) {
            Parameter[] parameters = method.getParameters();
            System.out.println("方法名:"+method.getName()+"\t方法返回值："+method.getReturnType()+"\t方法参数的个数:"+parameters.length);

        }

        //获取指定的公共方法
        Method method1 = aClass.getMethod("method1",String.class,int.class);
        method1.invoke(obj1,"aaaaaa",12);

        //获取指定私有方法
        Method method2 = aClass.getDeclaredMethod("method2", String.class, double.class);
        method2.setAccessible(true);
        String result = (String) method2.invoke("湖北黄石",12123.3);
        System.out.println(result);


    }
}


















